import sys
from typing import Dict

def calculate_checksum(data: bytes) -> int:
    """统一校验码计算：包头到校验码前所有字节的和取低8位"""
    # 校验码位置始终是倒数第二字节，包尾是最后一字节
    return sum(data[:-2]) % 256  # 包头到校验码前所有字节

def parse_response(data: bytes) -> Dict:
    """统一响应解析入口"""
    # 基础校验
    if len(data) < 3:
        raise ValueError(f"数据长度过短 ({len(data)} bytes)")
    if data[0] != 0xAA or data[-1] != 0x2F:
        raise ValueError(f"包头/包尾错误 (头:0x{data[0]:02X}, 尾:0x{data[-1]:02X})")
    
    # 计算并验证校验码
    expected_checksum = calculate_checksum(data)
    received_checksum = data[-2]
    if expected_checksum != received_checksum:
        raise ValueError(f"校验码错误 (计算:0x{expected_checksum:02X}, 接收:0x{received_checksum:02X})")
    
    # 获取命令类型
    cmd = data[2]
    parser = {
        0x20: parse_cmd20,
        0x21: parse_cmd21,
        0x22: parse_cmd22,
        0x23: parse_cmd23,
        0x24: parse_cmd24,
        0x25: parse_cmd25,
        0x26: parse_cmd26,
        0x27: parse_cmd27,
        0x28: parse_cmd28
    }.get(cmd, lambda x: {"error": f"未知命令 0x{cmd:02X}"})
    
    return parser(data)

# ------------------------- 各命令解析器 -------------------------
    """解析0X20响应：一键发送重量"""
def parse_cmd20(data: bytes) -> Dict:
    if len(data) != 15:
        raise ValueError("数据长度必须为15字节")

    # 校验包头包尾
    if data[0] != 0xAA or data[-1] != 0x2F:
        raise ValueError("无效的包头或包尾")
    
    """计算称重数据包校验码计算验证码"""
    # 范围：第1字节（包头）到第13字节（皮重结束）
    checksum_bytes = data[0:13]
    checksum =sum(checksum_bytes) % 256

    # # 验证校验码
    if checksum != data[-2]:
        raise ValueError(f"验证码错误，计算值0x{checksum:02X}，接收值0x{data[-2]:02X}")

    # 解析字段
    length = data[1]
    command = data[2]
    
    # 解析符号和单位
    sign_unit = data[3]
    if sign_unit == 0x81:
        sign, unit = "+", "KG"
    elif sign_unit == 0x01:
        sign, unit = "-", "KG"
    else:
        sign, unit = "", "UNKNOWN"
    
    # 解析数值
    decimal_places = data[4]
    net_weight = int.from_bytes(data[5:9], "big")
    stability = "稳定" if data[9] == 0x0A else "不稳定"
    tare = int.from_bytes(data[10:13], "big")

    # 应用小数位
    net_weight = (-1 if sign == "-" else 1) * net_weight / (10**decimal_places)
    tare = tare / (10**decimal_places)

    return {
        "作用":"命令1——0x20一键发送重量",
        # "包头": "0xAA",
        # "长度": length,
        # "命令": f"0x{command:02X}",
        # "符号": sign,
        # "单位": unit,
        # "小数位": decimal_places,
        "净重": f"{net_weight:.{decimal_places}f} {unit}",
        "稳定状态": stability,
        "皮重": f"{tare:.{decimal_places}f} {unit}",
        # "验证码": f"0x{data[-2]:02X}",
        "解析数据": f"{sign}{net_weight:.{decimal_places}f} {unit}",
        # "包尾": "0x2F"
    }

def parse_cmd21(data: bytes) -> Dict:
    """解析0X21响应：毛重/净重"""
    if len(data) != 11:
        raise ValueError("数据长度必须为11字节")

    # 校验包头包尾
    if data[0] != 0xAA or data[-1] != 0x2F:
        raise ValueError("无效的包头或包尾")
    
    # 解析字段
    length = data[1]
    command = data[2]
    

   
    
    # 解析符号和单位
    sign_unit = data[3]
    if sign_unit == 0x81:
        sign, unit = "+", "KG"
    elif sign_unit == 0x01:
        sign, unit = "-", "KG"
    else:
        sign, unit = "", "UNKNOWN"

    #  # 解析m毛重/净重
    # GN_weight = data[4]
    # if GN_weight == 0xCD:
    #     WHY_weight = "毛重Gross_weight"
    # elif GN_weight == 0xCE:
    #     WHY_weight = "净重Net_weight"
    # else:
    #     WHY_weight ="UNKNOWN净重or毛重"
    
    # 解析数值
    decimal_places = data[4]#小数位
    net_weight = int.from_bytes(data[5:9], "big")
    tare = int.from_bytes(data[5:9], "big")

    # 应用小数位
    net_weight = (-1 if sign == "-" else 1) * net_weight / (10**decimal_places)
    tare = tare / (10**decimal_places)

    return {
        "作用":"命令3——0x21取毛重或净重",
        # "包头": "0xAA",
        # "长度": length,
        # "命令": f"0x{command:02X}",
        # "符号": sign,
        # "单位": unit,
        # "小数位": decimal_places,
        "净重/皮重": f"{net_weight:.{decimal_places}f} {unit}",
        # "验证码": f"0x{data[-2]:02X}",
        "解析数据": f"{sign}{net_weight:.{decimal_places}f} {unit}",
        # "包尾": "0x2F"
    }

def parse_cmd22(data: bytes) -> Dict:
    """解析0X22响应：去皮"""
    if len(data) != 6:
        raise ValueError("数据长度必须为6字节")
    # 校验包头包尾
    if data[0] != 0xAA or data[-1] != 0x2F:
        raise ValueError("无效的包头或包尾")
    
    # 解析字段
    ACK = data[3]
    if ACK == 0x00:
        status = "去皮成功"
    elif ACK == 0x01:
        status = "拥堵"
    elif ACK == 0x02:
        status = "非法"
    else:
        status = "无效"

    # 范围：0到长度-2
    checksum_bytes = data[0:4]
    checksum =sum(checksum_bytes) % 256

    # # 验证校验码
    if checksum != data[-2]:
        raise ValueError(f"验证码错误，计算值0x{checksum:02X}，接收值0x{data[-2]:02X}")

    return {
        "作用":"命令3——去皮",
        "状态": status,
    }


def parse_cmd23(data: bytes) -> Dict:
    """解析0X23响应：回皮（皮重）"""
    if len(data) != 11:
        raise ValueError("数据长度必须为11字节")

    # 校验包头包尾
    if data[0] != 0xAA or data[-1] != 0x2F:
        raise ValueError("无效的包头或包尾")
        
    
    # 解析符号和单位
    sign_unit = data[3]
    if sign_unit == 0x81:
        sign, unit = "+", "KG"
    elif sign_unit == 0x01:
        sign, unit = "-", "KG"
    else:
        sign, unit = "", "UNKNOWN"
  
    # 解析数值
    decimal_places = data[4]#小数位
    net_weight = int.from_bytes(data[5:9], "big")
    tare = int.from_bytes(data[5:9], "big")

    # 应用小数位
    net_weight = (-1 if sign == "-" else 1) * net_weight / (10**decimal_places)
    tare = tare / (10**decimal_places)

    return {
        "作用":"命令4——0x23取毛重或净重",
        # "包头": "0xAA",
        # "长度": length,
        # "命令": f"0x{command:02X}",
        # "符号": sign,
        # "单位": unit,
        # "小数位": decimal_places,
        "皮重": f"{net_weight:.{decimal_places}f} {unit}",
        # "验证码": f"0x{data[-2]:02X}",
        "解析数据": f"{sign}{net_weight:.{decimal_places}f} {unit}",
        # "包尾": "0x2F"
    }

def parse_cmd24(data: bytes) -> Dict:
    """解析0X24响应：置零操作状态"""
    if len(data) != 6:
        raise ValueError("数据长度必须为6字节")
    # 校验包头包尾
    if data[0] != 0xAA or data[-1] != 0x2F:
        raise ValueError("无效的包头或包尾")
    
    # 解析字段
    ACK = data[3]
    if ACK == 0x00:
        status = "置零成功"
    elif ACK == 0x01:
        status = "拥堵"
    elif ACK == 0x02:
        status = "非法"
    else:
        status = "无效"

    # 范围：0到长度-2
    checksum_bytes = data[0:4]
    checksum =sum(checksum_bytes) % 256

    # # 验证校验码
    if checksum != data[-2]:
        raise ValueError(f"验证码错误，计算值0x{checksum:02X}，接收值0x{data[-2]:02X}")

    return {
        "作用":"命令6——置零",
        "状态": status,
    }

def parse_cmd25(data: bytes) -> Dict:
    """解析0X25响应：键盘事件"""
    return {
        "command": "0X25",
        "key1": data[3],
        "key2": data[4],
        "kb_status": data[5],
        "params": list(data[6:10]),
        "raw": data.hex(' ')
    }



def parse_cmd26(data: bytes) -> Dict:
    """解析0X26响应：单价下发"""
    if len(data) != 6:
        raise ValueError("数据长度必须为6字节")
    # 校验包头包尾
    if data[0] != 0xAA or data[-1] != 0x2F:
        raise ValueError("无效的包头或包尾")
    
    # 解析字段
    ACK = data[3]
    if ACK == 0x00:
        status = "单价下发成功"
    elif ACK == 0x01:
        status = "拥堵"
    elif ACK == 0x02:
        status = "非法"
    else:
        status = "无效"

    # 范围：0到长度-2
    checksum_bytes = data[0:4]
    checksum =sum(checksum_bytes) % 256

    # # 验证校验码
    if checksum != data[-2]:
        raise ValueError(f"验证码错误，计算值0x{checksum:02X}，接收值0x{data[-2]:02X}")

    return {
        "作用":"命令7——单价下发",
        "状态": status,
    }


def parse_cmd27(data: bytes) -> Dict:
    """解析0x27命令响应（净重+单价+电压+充电状态+称重状态）"""
    # 基础校验
    if len(data) != 16:
        raise ValueError("数据长度必须为16字节")
    if data[0] != 0xAA or data[-1] != 0x2F:
        raise ValueError("包头或包尾校验失败")

    # 计算校验码（包头到校验码前所有字节累加和）
    calc_checksum = sum(data[:-2]) % 256
    received_checksum = data[-2]
    if calc_checksum != received_checksum:
        raise ValueError(f"校验码错误 计算值:0x{calc_checksum:02X} 接收值:0x{received_checksum:02X}")

    # 解析字段
    ptr = 3  # 数据指针（跳过包头0xAA、长度0x0B、命令0x27）
    
    # 净重（4字节有符号整数），3~7，长4
    net_weight = int.from_bytes(data[ptr:ptr+4], byteorder='big', signed=True)
    ptr += 4#7
    
    # 单价（3字节无符号整数，单位分）7~10，长3
    unit_price = int.from_bytes(data[ptr:ptr+4], byteorder='big', signed=False)
    ptr += 3
    
    # 电压（2字节无符号整数，单位10mV）10~12，长2
    voltage = int.from_bytes(data[ptr:ptr+2], byteorder='big', signed=False)
    ptr += 2
    
    # 充电状态（1字节）
    charge_status = data[ptr]
    ptr += 1
    
    # 称重状态（1字节）
    weight_status = data[ptr]
    ptr += 1

    return {
        "包头": "0xAA",
        "长度": data[1],
        "命令": "0x27",
        "净重(kg)": f"{net_weight / 1000.0:.3f}",  # 假设小数位为3
        "单价(分)": unit_price,
        "电压(mV)": voltage * 10,  # 转换为实际毫伏
        # "充电状态": _parse_charge_status(charge_status),
        # "称重状态": _parse_weight_status(weight_status),
        "校验码": f"0x{received_checksum:02X}",
        "包尾": "0x2F"
    }

    # return {
    #     "command": "0X27",
    #     "net_weight": int.from_bytes(data[3:7], 'little') / 1000,  # Lint类型
    #     "price": int.from_bytes(data[7:10], 'little'),  # 单价（分）
    #     "voltage": int.from_bytes(data[10:12], 'little') * 10,     # 电压（mV）
    #     "charging": "充电中" if data[12] == 1 else "未充电",
    #     "status": {
    #         0: "正常",
    #         1: "负超重",
    #         2: "正超重",
    #         3: "AD过高",
    #         4: "AD过低"
    #     }.get(data[13], "未知状态"),
    #     "raw": data.hex(' ')
    # }



def parse_cmd28(data: bytes) -> Dict:
    """解析0X28响应：内码信息"""
    return {
        # "command": "0X28",
        "量程": int.from_bytes(data[3:6], 'big'),     # 3字节大端
        "砝码重量": int.from_bytes(data[6:9], 'big'),  # 3字节大端
        "AD值": int.from_bytes(data[9:13], 'little'), # 4字节小端
        "raw": data.hex(' ')
    }

# 1、一键发送重量：
# AA 01 20 CB 2F
# 2、取毛重：
# AA 02 21 00 CD 2F
# 3、取净重：
# AA 02 21 01 CE 2F
# 4、去皮:
# AA 01 22 CD 2F
# 5、取皮重：
# AA 01 23 CE 2F
# 6、置零：
# AA 01 24 CF 2F
# 7、下发单价：
# AA 04 26 00 00 00 D4 2F
# AA 04 26 00 00 64 38 2F
# 8、上传净重+单价+电压+充电状态：
# AA 01 27 D2 2F
# ------------------------- 快速测试 -------------------------
if __name__ == "__main__":
    test_cases = [

        "AA 0B 20 81 03 00 00 02 0D 0A 00 00 00 72 2F ",#20
        "AA 07 21 81 03 00 00 02 03 5B 2F  ",#21
        "AA 02 22 00 CE 2F",#22
        "AA 07 23 81 03 00 00 00 DC 34 2F",#23
        "AA 02 24 00 D0 2F  ",#24
        "AA 08 25 FF FF 00 00 00 00 00 D5 2F",#25
        "AA 02 26 00 D2 2F ",#26
        "AA 0B 27 00 00 01 7C 00 03 20 02 89 01 00 08 2F  ",#27

        # # 0X20示例数据（需要替换为实际数据）
        # "AA 0B 20 81 03 00 00 00 AF 0A 00 00 00 12 2F",
        # # 0X21示例数据
        # "AA 07 21 81 02 28 00 00 00 1A 2F",
        # # 0X22示例数据
        # "AA 02 22 00 CE 2F",
        # # 0X27示例数据
        # "AA 0B 27 00 00 03 E8 00 00 64 00 01 00 A0 2F"
    ]

    for hex_str in test_cases:
        print("\n" + "="*50)
        print(f"测试数据: {hex_str}")
        try:
            # 转换数据
            data = bytes.fromhex(hex_str.replace(" ", ""))
            result = parse_response(data)
            # 打印结果
            for key, value in result.items():
                print(f"{key:>12}: {value}")
        except Exception as e:
            print(f"解析失败: {str(e)}")
